#ifndef _CAISSE_H
#define _CAISSE_H

#include "Terrain.h"
/**
@brief Caisse brief description
<b>Description du module Caisse<\b>
@author Barry Bah Diallo
@file Caisse.h
@version 1.0
*/

/**
@brief  est une série de constantes prédéfinie pour les etats de la caisse
@enum typedef enum EtatCaisse{MARCHE_CAISSE,BLOQUEE_CAISSE,OBJECTIF_CAISSE}EtatCaisse;
*/
typedef enum EtatCaisse{MARCHE_CAISSE,OBJECTIF_CAISSE}EtatCaisse;


/**
@brief  on définie une structure( liste chainée) de caisse representé par '*' dans le terrain
@struct typedef struct {
	@var int x ;  
	@var int y ; 
	@var EtatCaisse etat_c ; 
	@var S_Caisse *suivant ;  @brief suivant est un poiteur vers Caisse
} Caisse;
*/

typedef struct S_Caisse
{
	int x;
	int y;
	EtatCaisse etat_c; 
	struct S_Caisse *suivant;
}Caisse;

/**
@brief  on définie une structure liste de caisse pour faire une liste sentinelle
@struct typedef struct {
	@var Caisse *prem ;  @brief prem est un pointeur vers ListeCaisse
} ListeCaisse;
*/

typedef struct S_ListeCaisse
{
	
	Caisse *prem;
	
}ListeCaisse;

/**
@brief Pré-condition: la liste chainée de caisses non initialié et le terrain initialisé
@brief Post-condition: la liste de caisses est initialisée  et non vide  a partir des '*' du terrain 
@fn void  caiInit( ListeCaisse *, const Terrain *);
@param [in ] pTer
@param [in out] lCai
*/

void  caiInit(ListeCaisse *, const Terrain *);

/**
@brief caiGauche permet de deplacer la caisse vers la gauche d'une position
@fn void caiGauche(Caisse *, const Terrain *,int *);
@param [in out] pCai
@param [in] pTer
@param [in out] possible
*/

void caiGauche(Caisse *, const Terrain *,int *);

/**
@brief caiDroite permet de deplacer la caisse vers la droite d'une position
@fn void caiDroite(Caisse *, const  Terrain *, int *);
@param [in out] pCai
@param [in] pTer
@param [in out] possible
*/
void caiDroite(Caisse *, const  Terrain *, int *);

/**
@brief caiHaut permet de deplacer la caisse vers le haut d'une position
@fn  void caiHaut(Caisse *, const Terrain *, int *);
@param [in out] pCai
@param [in] pTer
@param [in out] possible
*/

void caiHaut(Caisse *, const Terrain *, int *);

/** 
@brief caiBas permet de deplacer la caisse vers le bas d'une position
@fn void caiBas(Caisse *, const Terrain *, int *);
@param [in out] pCai
@param [in] pTer
@param [in out] possible
*/

void caiBas(Caisse *, const Terrain *, int *);
/**
@brief caiGetX recupère la coordonee suivant x de la caisse passée en paramètre
@fn int caiGetX(const Caisse *);
@param [in ] pCai
*/
int caiGetX(const Caisse *);
/**
@brief caiGetY recupère la coordonee suivant y de la caisse  passée en paramètre
@fn void caiGetY(const Caisse *);
@param [in ] pCai
@return retourne la coordonee suivant y de la caisse
*/
int caiGetY(const Caisse *);

/**
@brief caiGetEtat recupère l'etat de la caisse  passée en paramètre
@fn EtatCaisse caiGetEtat(const Caisse *);
@param [in ] pCai
*/
EtatCaisse caiGetEtat(const Caisse *);


/**
@brief caiGetPrem recupère  l'adresse de la liste de caisse  passée en paramètre
@fn Caisse *caiGetPrem(const ListeCaisse *);
@param [in ] pLcai
@return retourne un pointeur sur le prémier élement de la liste de caisses
*/
Caisse *caiGetPrem(const ListeCaisse *);


/**
@brief caiGetSuivant recupère  un pointeur sur la caisse suivant  la caisse passée en paramètre
@fn Caisse *caiGetSuivant(Caisse *);
@param [in ] pCai
@return retourne un pointeur sur la caisse suivant la caisse passé en paramètre
*/
Caisse *caiGetSuivant(Caisse *);


/**
@brief caiRecherche  recherche  une caisse a la position (x,y) puis retourne un pointeur sur cette  caisse 
@fn Caisse *caiRecherche( const ListeCaisse *, int , int );
@param [in ] pLcai
@param [in ] x
@param [in ] y
*/
Caisse *caiRecherche( const ListeCaisse *, int , int );

/**
@brief caiLibere libere toute l'espace memoire occupee par la liste de caisse
@fn void caiLibere(ListeCaisse *);
@param [in] pLcai
*/
void caiLibere(ListeCaisse *);


/**
@brief caiTestRegression effectue une serie de teste pour toute les fonctions du module caisse
@fn void caiTestRegression();
*/
void caiTestRegression();


#endif
